package mk.jug.academy.service;

import java.util.List;

import mk.jug.academy.model.Course;
import mk.jug.academy.model.Lecturer;
import mk.jug.academy.model.Page;
import mk.jug.academy.model.Student;
import mk.jug.academy.model.status.CourseStatus;


/**
 * A contract for the services regarding
 * a {@link Course} in the system. 
 * 
 * @author Ice.Penov
 */
public interface CourseService {

	/**
	 * Submits a new {@link Course} in the system.
	 */
	void submitNewCourse(Course course);
	
	/**
	 * Fetches all courses, in a paged manner.
	 */
	Page<Course> listAll(int pageNumber, int itemsPerPage);
	
	/**
	 * Fetches the currently {@link CourseStatus#HATCHING} courses
	 * in the system, in a paged manner.
	 */
	Page<Course> listHatching(int pageNumber, int itemsPerPage);

	/**
	 * Fetches the currently {@link CourseStatus#AVAILABLE} courses
	 * in the system, in a paged manner. 
	 */
	Page<Course> listAvailable(int pageNumber, int itemsPerPage);
	
	/**
	 * Fetches all the {@link CourseStatus#AVAILABLE} courses.
	 */
	List<Course> fetchAvailable();

	/**
	 * Fetches the currently {@link CourseStatus#IN_PROGRESS} courses
	 * in the system, in a paged manner.
	 */
	Page<Course> listInProgress(int pageNumber, int itemsPerPage);
	
	/**
	 * Fetches the currently {@link CourseStatus#DEACTIVATED} courses
	 * in the system.
	 */
	Page<Course> listDeactivated(int pageNumber, int itemsPerPage);

	/**
	 * Promotes an existing course from
	 * hatching to available pool.
	 */
	void hatchCourse(Course course);
	
	/**
	 * Start a course (moves is to the IN_PROGRESS status).
	 */
	void startCourse(Course course);
	
	/**
	 * Deactivates a course (moves it to the DEACTIVATED status).
	 */
	void deactivateCourse(Course course);
	
	/**
	 * Assigns a {@link Lecturer} to a {@link Course}
	 */
	void assignLecturer(Course course, Lecturer lecturer);
	
	/**
	 * Finishes a running course (moves it back to the AVAILABLE state).
	 */
	void finishCourse(Course course);
			
	/**
	 * Returns the {@link Course} for the given ID.
	 */
	Course load(Long id);
	
	/**
	 * Removes a {@link Lecturer} from the given course. 
	 */
	void removeLecturer(Course course, Lecturer lecturer);
	
	/**
	 * Save the changes.
	 */
	void saveChanges(Course course);
	
	/**
	 * Assigns a {@link Student} to a {@link Lecturer}.
	 */
	void assignStudent(Course course, Student student);
	
	/**
	 * Gets the {@link Student}s for the given {@link Course}.
	 */
	List<Student> fetchStudentsForCourse(Course course1);

	/**
	 * Removes {@link Student} from the given {@link Course}.
	 */
	void removeStudent(Course cours1, Student student);
	
}
